/**
 * 
 */
package atom.core3.hibernate;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;

import org.apache.log4j.Logger;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.springframework.orm.hibernate4.SessionFactoryUtils;



/**
 * <p>
 * Title: 数据库事务管理器，负责事务处理
 * </p>
 * <p>
 * Description:
 * </p>
 * <p>
 * Copyright: Copyright (c) 2010
 * </p>
 * <p>
 * </p>
 * 
 * @author 赵明才
 * @version 1.0
 */
public class MutiDatabaseManager
{
	/**
	 * Log4J Logger for this class
	 */
	private static final Logger logger = Logger.getLogger(MutiDatabaseManager.class);
    private static HashMap<String,MutiDatabaseManager> instanceMap = new HashMap();
    private String configFileKey ;
	private MutiDatabaseManager()
	{
	}
	public static MutiDatabaseManager getInstance (String key) {
		MutiDatabaseManager instance;
		instance = instanceMap.get(key);
		if (null == instance) 
		{	
			instance = new MutiDatabaseManager();
			instance.configFileKey=key;
			instanceMap.put(key, instance);
		}
		return instance;
	}

	/**
	 * 判断当前线程是否已经处于一个事务中
	 * 
	 * @return
	 */
	public  boolean isInTransaction()
	{
		if (null == MutiHibernateSessionFactory.getInstance(configFileKey).getThreadLocal().get())
		{
			return false;
		} else
		{
			return true;
		}
	}



	// 判断Session的事务是否提交，就是不应该的。
	// Session永远处于事务中，因为，一旦一个Transaction结束了,马上就开始了一个新的Transaction public
	boolean isInTransaction_no_use(Session session)
	{
		boolean bRet;
		if (null != session)
		{
			bRet = session.getTransaction().wasCommitted();
			return bRet;
		} else
			return false;
	}

	public boolean isInTransaction_no_use()
	{
		Session session = (Session) getSession();
		return isInTransaction_no_use(session);
	}

	/**
	 * 获取当前线程的数据库操作Session
	 * 
	 * @return
	 */
	public  Session getSession()
	{
		return MutiHibernateSessionFactory.getInstance(configFileKey).getSession();
	}
	public  Session getNewSession()
	{
		return MutiHibernateSessionFactory.getInstance(configFileKey).getNewSession();
	}

	/**
	 * 在当前线程开始一个新事务，如果当前线程已经有事务，先强制回滚它。
	 * 
	 */
	public Transaction beginTransaction()
	{
		// HibernateSessionFactory.getSession().getTransaction().begin()
		// Transaction tx =
		// HibernateSessionFactory.getSession().beginTransaction();
		// 这两句是等价的
		//如果原来存在有事务，安全起见，强行回滚
		if (isInTransaction())
		{
			logger.debug("强行回滚旧事务................");
			try
			{
				rollbackTransaction();
			}
			catch (Exception e)
			{
				logger.error("回滚残余事务失败，失败原因：" + e);
			}
		}
		
		Session session = (Session) getSession();
		Transaction tx = beginTransaction(session);

		// Transaction tx = session.getTransaction();
		// tx.begin();

		return tx;
	}

	/**
	 * 在当前线程开始一个新事务，并指定它的数据库配置文件，如果当前线程已经有事务，先强制回滚它。
	 * 
	 */
	public Transaction beginTransaction(Session s) throws HibernateException
	{
		return s.beginTransaction();
	}

	public void commitTransaction()
	{
		// HibernateSessionFactory.getSession().getTransaction().commit();
		Session session = (Session) getSession();
		commitTransaction(session);

	}

	public void commitTransaction(Session s)
	{
		try
		{
			s.getTransaction().commit();
			s.flush();
		} catch (HibernateException e)
		{
			s.getTransaction().rollback();
			s.flush();
			logger.debug("无法提交事务，被迫回滚................");
			throw e;
		} finally
		{
			// 需要关闭Session吗？害怕Session泄露 ThreadLocal一直占用？
			closeSession();

		}
	}

	public void rollbackTransaction()
	{
		// HibernateSessionFactory.getSession().getTransaction().rollback();
		Session session = (Session) getSession();
		rollbackTransaction(session);
	}

	public void rollbackTransaction(Session s)
	{
		s.getTransaction().rollback();
		s.flush();
		// 需要关闭Session吗？害怕Session泄露 ThreadLocal一直占用？
		closeSession();

	}

	// 关闭指定Session
	public void closeSession(Session session) throws HibernateException
	{
		if (null != session && session.isOpen())
		{
			session.close();
		}
	}

	// 关闭当前Session
	public void closeSession() throws HibernateException
	{
		HibernateSessionFactory.closeSession();
	}


	static public void showSessionState(Session s)
	{

		// bRet = s.isDirty();
		// bRet = s.isOpen();
		// bRet = s.getTransaction().isActive();
		// bRet = s.getTransaction().wasCommitted();

		if (s != null)
		{
			System.out.println("Session:isDirty()=" + s.isDirty() + ";isOpen()=" + s.isOpen());
			if (s.getTransaction() != null)
				System.out.println("Transaction:isActive()=" + s.getTransaction().isActive() + ";wasCommitted()="
						+ s.getTransaction().wasCommitted());
			else
				System.out.println("Transaction:null");
		}
	}

	public void showSessionState()
	{
		Session session = (Session) getSession();
		showSessionState(session);
	}


}
